Support having a generic writer instead of a termcolor StandardStream
authorNick Cameron <ncameron@mozilla.com>
Fri, 16 Jun 2017 02:57:27 +0000 (14:57 +1200)
committerNick Cameron <ncameron@mozilla.com>
Sat, 17 Jun 2017 04:38:50 +0000 (16:38 +1200)
This is requied by the RLS (and presumably any other client who wants to use Cargo as a lib and redirect output)

src/cargo/core/shell.rs
src/cargo/lib.rs
src/cargo/ops/cargo_new.rs
src/cargo/ops/cargo_rustc/job_queue.rs
src/cargo/ops/registry.rs

index 1dfeb375c52da1a34b0f9d3085e17321c25d8c1b..d6edde59ca4d3d814ea132c2ed353a3f11fe50a3 100644 (file)
@@ -15,9 +15,13 @@ pub enum Verbosity {
 }
 
 pub struct Shell {
-    err: StandardStream,
+    err: ShellOut,
     verbosity: Verbosity,
-    choice: ColorChoice,
+}
+
+enum ShellOut {
+    Write(Box<Write>),
+    Stream(StandardStream, ColorChoice),
 }
 
 #[derive(PartialEq, Clone, Copy)]
@@ -30,9 +34,18 @@ pub enum ColorChoice {
 impl Shell {
     pub fn new() -> Shell {
         Shell {
-            err: StandardStream::stderr(ColorChoice::CargoAuto.to_termcolor_color_choice()),
+            err: ShellOut::Stream(
+                StandardStream::stderr(ColorChoice::CargoAuto.to_termcolor_color_choice()),
+                ColorChoice::CargoAuto,
+            ),
+            verbosity: Verbosity::Verbose,
+        }
+    }
+
+    pub fn from_write(out: Box<Write>) -> Shell {
+        Shell {
+            err: ShellOut::Write(out),
             verbosity: Verbosity::Verbose,
-            choice: ColorChoice::CargoAuto,
         }
     }
 
@@ -44,24 +57,13 @@ impl Shell {
         match self.verbosity {
             Verbosity::Quiet => Ok(()),
             _ => {
-                self.err.reset()?;
-                self.err.set_color(ColorSpec::new()
-                                        .set_bold(true)
-                                        .set_fg(Some(color)))?;
-                if justified {
-                    write!(self.err, "{:>12}", status)?;
-                } else {
-                    write!(self.err, "{}", status)?;
-                }
-                self.err.reset()?;
-                write!(self.err, " {}\n", message)?;
-                Ok(())
+                self.err.print(status, message, color, justified)
             }
         }
     }
 
-    pub fn err(&mut self) -> &mut StandardStream {
-        &mut self.err
+    pub fn err(&mut self) -> &mut Write {
+        self.err.as_write()
     }
 
     pub fn status<T, U>(&mut self, status: T, message: U) -> CargoResult<()>
@@ -117,23 +119,68 @@ impl Shell {
     }
 
     pub fn set_color_choice(&mut self, color: Option<&str>) -> CargoResult<()> {
-        let cfg = match color {
-            Some("always") => ColorChoice::Always,
-            Some("never") => ColorChoice::Never,
+        if let ShellOut::Stream(ref mut err, ref mut cc) =  self.err {
+            let cfg = match color {
+                Some("always") => ColorChoice::Always,
+                Some("never") => ColorChoice::Never,
+
+                Some("auto") |
+                None => ColorChoice::CargoAuto,
+
+                Some(arg) => bail!("argument for --color must be auto, always, or \
+                                    never, but found `{}`", arg),
+            };
+            *cc = cfg;
+            *err = StandardStream::stderr(cfg.to_termcolor_color_choice());
+        }
+        Ok(())
+    }
 
-            Some("auto") |
-            None => ColorChoice::CargoAuto,
+    pub fn color_choice(&self) -> ColorChoice {
+        match self.err {
+            ShellOut::Stream(_, cc) => cc,
+            ShellOut::Write(_) => ColorChoice::Never,
+        }
+    }
+}
 
-            Some(arg) => bail!("argument for --color must be auto, always, or \
-                                never, but found `{}`", arg),
-        };
-        self.choice = cfg;
-        self.err = StandardStream::stderr(cfg.to_termcolor_color_choice());
-        return Ok(());
+impl ShellOut {
+    fn print(&mut self,
+             status: &fmt::Display,
+             message: &fmt::Display,
+             color: Color,
+             justified: bool) -> CargoResult<()> {
+        match *self {
+            ShellOut::Stream(ref mut err, _) => {
+                err.reset()?;
+                err.set_color(ColorSpec::new()
+                                    .set_bold(true)
+                                    .set_fg(Some(color)))?;
+                if justified {
+                    write!(err, "{:>12}", status)?;
+                } else {
+                    write!(err, "{}", status)?;
+                }
+                err.reset()?;
+                write!(err, " {}\n", message)?;
+            }
+            ShellOut::Write(ref mut w) => {
+                if justified {
+                    write!(w, "{:>12}", status)?;
+                } else {
+                    write!(w, "{}", status)?;
+                }
+                write!(w, " {}\n", message)?;
+            }
+        }
+        Ok(())
     }
 
-    pub fn color_choice(&self) -> ColorChoice {
-        self.choice
+    fn as_write(&mut self) -> &mut Write {
+        match *self {
+            ShellOut::Stream(ref mut err, _) => err,
+            ShellOut::Write(ref mut w) => w,
+        }
     }
 }
 
index 3f03697d4dd22cc84b18f3a188f0a6e92a5194b2..5a1c3de149c9397e2741c24f8091a8f374e246c4 100755 (executable)
@@ -33,7 +33,6 @@ extern crate termcolor;
 extern crate toml;
 extern crate url;
 
-use std::io::Write;
 use std::fmt;
 use std::error::Error;
 
index fdff07ee380c7db8ac7fb0c801fbb533cef74f4b..31c308bb9b418776596cce72e9b383d3351cefac 100644 (file)
@@ -1,7 +1,6 @@
 use std::collections::BTreeMap;
 use std::env;
 use std::fs;
-use std::io::Write;
 use std::path::Path;
 
 use serde::{Deserialize, Deserializer};
index aec3e3c853c412160d4ae3a0bcf171e31bae763b..1934e2c8b745dcc1dbbcb9a502c57786a2488b89 100644 (file)
@@ -1,7 +1,7 @@
 use std::collections::HashSet;
 use std::collections::hash_map::HashMap;
 use std::fmt;
-use std::io::{self, Write};
+use std::io;
 use std::mem;
 use std::sync::mpsc::{channel, Sender, Receiver};
 
index 01a5e0710775c121bc01948dba4eb5cf45957d5a..35ec30257c223cc2071a366b84c49a303ae99a14 100644 (file)
@@ -1,6 +1,5 @@
 use std::env;
 use std::fs::{self, File};
-use std::io::Write;
 use std::iter::repeat;
 use std::time::Duration;